﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace VietImage.Models
{
    public partial class Payment
    {
        #region Properties
        public User User
        {
            get
            {
                return this.GetUser();
            }
        }

        public Status Status
        {
            get
            {
                return this.GetStatus();
            }
        }

        public Image Image
        {
            get
            {
                return this.GetImage();
            }
        }
        #endregion

        #region Methods
        public User GetUser()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Users.Where(p => p.ID == this.ID_User);
            if (v.Count() == 0)
                return null;
            return v.First();
        }

        public Status GetStatus()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Status.Where(p => p.ID == this.ID_Status);
            if (v.Count() == 0)
                return null;
            return v.First();
        }

        public Image GetImage()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Images.Where(p => p.ID == this.ID_Image);
            if (v.Count() == 0)
                return null;
            return v.First();
        }

        public List<ErrorItem> PayForImage(int id_User, int id_Lang)
        {
            List<ErrorItem> errorList = new List<ErrorItem>();

            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();

            int errorMess = _db.PayForImage(id_User, this.ID_User, this.ID_Image);

            
                if(errorMess != 1) errorList.Add(new ErrorItem("ErrorMessage", _db.ErrorMessages.Single(p => p.ID_ErrorMessage == errorMess && p.ID_Language == id_Lang).Description));

            return errorList;
        }
        #endregion

        #region Static Methods
        public static bool BoughtByUser(int id_User, int id_Image)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            Payment p = _db.Payments.Where(pm => pm.ID_User == id_User && pm.ID_Image == id_Image).First();
            if (p == null)
                return false;
            return true;
        }

        public static Payment Parse(System.Object value)
        {
            Payment temp = null;
            try
            {
                temp = (Payment)value;
            }
            catch (Exception ex)
            {
            }
            return temp;
        }

        public static long GetFunds(DateTime date)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();

            long funds = long.Parse((from p in _db.Payments
                                     join c in _db.Customers on p.ID_User equals c.ID_User
                                     where p.ID_Status == 5 && p.BoughtTime.Date == date.Date
                                     select c.Price).Sum().ToString());

            return 0;
        }

        public static long GetFunds(int month, int year)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();

            long funds = long.Parse((from p in _db.Payments
                                     join c in _db.Customers on p.ID_User equals c.ID_User
                                     where p.ID_Status == 5 && p.BoughtTime.Month == month && p.BoughtTime.Year == year
                                     select c.Price).Sum().ToString());

            return 0;
        }

        public static long GetFunds(DateTime beginDate, DateTime endDate)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();

            long funds = long.Parse((from p in _db.Payments
                                     join c in _db.Customers on p.ID_User equals c.ID_User
                                     where p.ID_Status == 5 && p.BoughtTime.Date >= beginDate.Date && p.BoughtTime.Date <= endDate.Date
                                     select c.Price).Sum().ToString());

            return 0;
        }

        public static List<Payment> GetList()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Payments.OrderByDescending(p => p.ID);
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }

        public static List<Payment> GetList(DateTime boughtTime)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Payments.Where(p => p.BoughtTime.Date == boughtTime.Date);
            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p=>p.ID).ToList();
        }

        public static List<Payment> GetListAvailable()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Payments.Where(p => p.ID_Status != 2);
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }

        public static List<Payment> GetListNotAvailable()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Payments.Where(p => p.ID_Status == 2);
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }

        public static List<User> GetBuyer()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = from p in _db.Payments
                       join u in _db.Users on p.ID_User equals u.ID
                       select u;

            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p => p.ID).ToList();
        }

        public static List<User> GetBuyer(DateTime date)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = from p in _db.Payments
                       join u in _db.Users on p.ID_User equals u.ID
                       where p.BoughtTime.Date == date.Date
                       select u;
            
            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p=>p.ID).ToList();
        }

        public static List<User> GetDebtor()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = from p in _db.Payments
                       join u in _db.Users on p.ID_User equals u.ID
                       where p.ID_Status == 4
                       select u;
            
            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p=>p.ID).ToList();
        }

        public static List<User> GetPaidDebtor()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = from p in _db.Payments
                       join u in _db.Users on p.ID_User equals u.ID
                       where p.ID_Status == 5
                       select u;
            
            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p=>p.ID).ToList();
        }

        public static List<User> GetDebtor(DateTime boughtTime)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = from p in _db.Payments
                       join u in _db.Users on p.ID_User equals u.ID
                       where p.ID_Status == 4 && p.BoughtTime == boughtTime
                       select u;
            
            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p=>p.ID).ToList();
        }

        public static List<User> GetDebtor(int month, int year)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = from p in _db.Payments
                       join u in _db.Users on p.ID_User equals u.ID
                       where p.ID_Status == 4 && p.BoughtTime.Month == month && p.BoughtTime.Year == year
                       select u;
            
            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p=>p.ID).ToList();
        }

        public static List<User> GetDebtor(DateTime beginDate,DateTime endDate)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = from p in _db.Payments
                       join u in _db.Users on p.ID_User equals u.ID
                       where p.ID_Status == 4 && p.BoughtTime >= beginDate && p.BoughtTime <= endDate
                       select u;
            
            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p=>p.ID).ToList();
        }

        public static List<User> GetPaidDebtor(DateTime boughtTime)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = from p in _db.Payments
                       join u in _db.Users on p.ID_User equals u.ID
                       where p.ID_Status == 5 && p.BoughtTime == boughtTime
                       select u;
            
            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p=>p.ID).ToList();
        }

        public static List<User> GetPaidDebtor(int month, int year)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = from p in _db.Payments
                       join u in _db.Users on p.ID_User equals u.ID
                       where p.ID_Status == 5 && p.BoughtTime.Month == month && p.BoughtTime.Year == year
                       select u;
            
            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p=>p.ID).ToList();
        }

        public static List<User> GetPaidDebtor(DateTime beginDate, DateTime endDate)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = from p in _db.Payments
                       join u in _db.Users on p.ID_User equals u.ID
                       where p.ID_Status == 5 && p.BoughtTime >= beginDate && p.BoughtTime <= endDate
                       select u;
            
            if (v.Count() == 0)
                return null;
            return v.OrderByDescending(p=>p.ID).ToList();
        }

        private static List<ErrorItem> InputInfomationValidation(Payment payment)
        {
            List<ErrorItem> errorList = new List<ErrorItem>();
            if (payment.ID_User < 1)
                errorList.Add(new ErrorItem("ID_User", "User is required"));
            if (payment.ID_Image < 1)
                errorList.Add(new ErrorItem("ID_Image", "Image is required."));
            if (payment.ID_Status < 1)
                errorList.Add(new ErrorItem("ID_Status", "Status is required."));
            return errorList;
        }

        public static List<ErrorItem> ChangeInformation(Payment ic, int id_User, int id_Lang)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            List<ErrorItem> errorList = InputInfomationValidation(ic);
            if (errorList.Count == 0)
            {
                Payment oi = _db.Payments.Single(p => p.ID == ic.ID);
                int errorMess = _db.ChangePayment(id_User, ic.ID, ic.ID_Status, 0, 0);

                if(errorMess != 1) errorList.Add(new ErrorItem("ErrorMessage", _db.ErrorMessages.Single(p => p.ID_ErrorMessage == errorMess && p.ID_Language == id_Lang).Description));
            }
            return errorList;
        }

        public static List<ErrorItem> ChangeInformation(Payment ic, int id_User, int id_Log, int id_Lang)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            List<ErrorItem> errorList = InputInfomationValidation(ic);
            if (errorList.Count == 0)
            {
                Payment oi = _db.Payments.Single(p => p.ID == ic.ID);
                int errorMess = _db.ChangePayment(id_User, ic.ID, ic.ID_Status, id_Log, 1);

                if(errorMess != 1) errorList.Add(new ErrorItem("ErrorMessage", _db.ErrorMessages.Single(p => p.ID_ErrorMessage == errorMess && p.ID_Language == id_Lang).Description));
            }
            return errorList;
        }
        #endregion

        #region Search

        private static String BuildQuery(Dictionary<String, System.Object> parametersList, Dictionary<String, bool> exactList)
        {
            String query = "";

            DateTime noValue = new DateTime(2000, 1, 1);

            foreach (KeyValuePair<String, System.Object> kvp in parametersList)
            {
                if (kvp.Key == "ID" || kvp.Key == "ID_Image" || kvp.Key == "ID_User" || kvp.Key == "ID_Status")
                {
                    if (int.Parse(kvp.Value.ToString()) >= 1)
                        query += kvp.Key + " = " + int.Parse(kvp.Value.ToString());
                }
                else if (kvp.Key == "BoughtTime")
                {
                    if (DateTime.Parse(kvp.Value.ToString()) != noValue)
                        query += "BoughtTime" + " = " + DateTime.Parse(kvp.Value.ToString()).ToString("yyyy-MM-dd") + "";
                }
            }

            if (parametersList.ContainsKey("BoughtbeginDate") && parametersList.ContainsKey("BoughtendDate"))
            {
                query += " DATEDIFF(day, " + DateTime.Parse(parametersList["BoughtendDate"].ToString()).ToString("yyyy-MM-dd") + " , BoughtTime) >= 0";
                query += " DATEDIFF(day, BoughtTime , " + DateTime.Parse(parametersList["BoughtbeginDate"].ToString()).ToString("yyyy-MM-dd") + ") >= 0";
            }

            return query;
        }

        public static System.Object GetPayment(Dictionary<String, System.Object> parametersList, Dictionary<String, bool> exactList, bool oneRow)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            String query = BuildQuery(parametersList, exactList);
            var v = _db.ExecuteQuery<Payment>(query);
            if (oneRow)
            {
                if (v.Count() == 0)
                    return null;
                return v.First();
            }
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }

        #endregion
    }
}